#include "../head.h"

void *th_recv(void *arg)
{
    int connectfd = *((int *)arg);
     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
    while (1)
    {
        char buf[1024] = {0};
        ssize_t recv_res = recv(connectfd, buf, sizeof(buf), 0);
        if (recv_res < 0)
        {
            printf("接收失败\n");
            continue;
        }
        else if (recv_res == 0)
        {
            printf("客户端断开连接\n");
            break;
        }
        printf("接收到的数据：%s\n", buf);
    }
}

int main()
{
    printf("服务器启动\n");
    // 1.创建套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        printf("socket error\n");
        return -1;
    }
    // 2.创建结构体
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;                          // 使用ipv4
    server_addr.sin_port = htons(6153);                        // 端口号 htons() 主机字节序转网络字节序（大端序） ntohs() 网络字节序转主机字节序
    server_addr.sin_addr.s_addr = inet_addr("192.168.47.198"); // ip地址 inet_addr() 主机ip转网络ip  inet_ntoa() 网络ip转主机ip
    int optval = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
    // 3.绑定ip地址和端口
    int bind_res = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (bind_res < 0)
    {
        printf("bind error\n");
        return -1;
    }
    // 4.设置监听
    int listen_res = listen(sockfd, 5);
    if (listen_res < 0)
    {
        printf("listen error\n");
        return -1;
    }
    while (1)
    {
        // 创建Client端地址结构体
        struct sockaddr_in client_addr;
        memset(&client_addr, 0, sizeof(client_addr));
        // 5.接受客户端的连接  返回已连接的套接字文件描述符
        int Client_len = sizeof(client_addr);
        int connectfd = accept(sockfd, (struct sockaddr *)&client_addr, &Client_len);
        if (connectfd < 0)
        {
            printf("accept error\n");
            continue;
        }
        printf("client ip: %s, port: %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
        pthread_t thread;
        pthread_create(&thread, NULL, th_recv, &connectfd);
        while (1)
        {
            char buf[1024] = {0};
            scanf("%s", buf);
            send(connectfd, buf, strlen(buf), 0);
            if (strcmp(buf, "exit") == 0)
            {
                pthread_cancel(thread);
                break;
            }
        }
        // 7.关闭套接字
        close(connectfd);
        printf("服务器关闭connectfd\n");
    }

    close(sockfd);
    return 0;
}